using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.IO;
using System.Text.RegularExpressions;

namespace CodRevit.ViewModels
{
    /// <summary>
    /// 批量添加共享参数视图模型
    /// </summary>
    public partial class AddParameterViewModel : ObservableObject
    {
        private readonly UIApplication _uiapp;
        private readonly Window _window;
        private readonly ExternalEvent _externalEvent;
        private readonly AddParameterHandler _handler;
        private readonly ICollection<ElementId> _selectedElementIds;

        [ObservableProperty]
        private ObservableCollection<FamilyTypeInfo> _familyTypes = new ObservableCollection<FamilyTypeInfo>();

        [ObservableProperty]
        private ObservableCollection<SharedParameterInfo> _parameters = new ObservableCollection<SharedParameterInfo>();

        [ObservableProperty]
        private string _statusMessage = "准备就绪";

        [ObservableProperty]
        private bool _isProcessing = false;

        [ObservableProperty]
        private double _progressValue = 0;

        [ObservableProperty]
        private string _progressText = "0/0";

        // 可选的参数分组列表
        [ObservableProperty]
        private ObservableCollection<ParameterGroupInfo> _availableGroups = new ObservableCollection<ParameterGroupInfo>();

        // 全局参数设置
        [ObservableProperty]
        private bool _globalIsInstance = true; // 默认为实例参数

        [ObservableProperty]
        private BuiltInParameterGroup _globalParameterGroup = BuiltInParameterGroup.PG_GEOMETRY; // 默认为几何分组

        // 共享参数文件路径
        [ObservableProperty]
        private string _sharedParameterFilePath = string.Empty;

        public AddParameterViewModel(
            UIApplication uiapp,
            Window window,
            ExternalEvent externalEvent,
            AddParameterHandler handler,
            ICollection<ElementId> selectedElementIds)
        {
            _uiapp = uiapp;
            _window = window;
            _externalEvent = externalEvent;
            _handler = handler;
            _selectedElementIds = selectedElementIds;

            // 初始化默认共享参数文件路径
            SharedParameterFilePath = Path.Combine(
                Path.GetDirectoryName(typeof(AddParameterViewModel).Assembly.Location),
                "config_shareparameter.txt");

            InitializeParameterGroups();
            InitializeData();
        }

        private void InitializeParameterGroups()
        {
            AvailableGroups = new ObservableCollection<ParameterGroupInfo>
            {
                new ParameterGroupInfo(BuiltInParameterGroup.PG_GENERAL, "常规"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_GEOMETRY, "尺寸标注"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_CONSTRAINTS, "约束"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_TEXT, "文字"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_MATERIALS, "材质"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_IDENTITY_DATA, "标识数据"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_PHASING, "阶段"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_CONSTRUCTION, "构造"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_GRAPHICS, "图形"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_VISIBILITY, "可见性"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_DATA, "数据"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_ANALYTICAL_MODEL, "分析模型"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_STRUCTURAL, "结构"),
                new ParameterGroupInfo(BuiltInParameterGroup.PG_IFC, "IFC参数")
            };
        }

        private void InitializeData()
        {
            try
            {
                // 分析选中的族实例，提取唯一的族（而非族类型）
                Document doc = _uiapp.ActiveUIDocument.Document;
                var familyGroups = new Dictionary<ElementId, FamilyTypeInfo>();

                foreach (var elementId in _selectedElementIds)
                {
                    var element = doc.GetElement(elementId);
                    if (element is FamilyInstance famInst && famInst.Symbol != null)
                    {
                        var familySymbol = famInst.Symbol;
                        var family = familySymbol.Family;
                        var familyId = family.Id; // 使用族 ID 而非族类型 ID

                        if (!familyGroups.ContainsKey(familyId))
                        {
                            // 计算该族的所有类型数量
                            var allTypesOfFamily = new FilteredElementCollector(doc)
                                .OfClass(typeof(FamilySymbol))
                                .Cast<FamilySymbol>()
                                .Where(fs => fs.Family.Id == familyId)
                                .Count();

                            familyGroups[familyId] = new FamilyTypeInfo
                            {
                                FamilyTypeId = familyId, // 存储族 ID
                                FamilyTypeName = $"{family.Name} ({allTypesOfFamily} 个类型)", // 显示族名和类型数量
                                FamilyName = family.Name,
                                InstanceCount = 0,
                                IsSelected = true
                            };
                        }
                        familyGroups[familyId].InstanceCount++;
                    }
                }

                FamilyTypes = new ObservableCollection<FamilyTypeInfo>(familyGroups.Values);

                // 加载共享参数配置
                LoadSharedParameters();

                StatusMessage = $"发现 {FamilyTypes.Count} 个族，{Parameters?.Count ?? 0} 个共享参数";
            }
            catch (Exception ex)
            {
                StatusMessage = $"初始化失败：{ex.Message}";
            }
        }

        private void LoadSharedParameters()
        {
            try
            {
                if (string.IsNullOrEmpty(SharedParameterFilePath))
                {
                    StatusMessage = "未设置共享参数文件路径";
                    Parameters = new ObservableCollection<SharedParameterInfo>();
                    return;
                }

                if (!File.Exists(SharedParameterFilePath))
                {
                    StatusMessage = $"未找到共享参数配置文件: {SharedParameterFilePath}";
                    Parameters = new ObservableCollection<SharedParameterInfo>();
                    return;
                }

                var parameters = new List<SharedParameterInfo>();
                var lines = File.ReadAllLines(SharedParameterFilePath, System.Text.Encoding.UTF8);
                bool inParamSection = false;
                int lineNumber = 0;

                foreach (var line in lines)
                {
                    lineNumber++;
                    var trimmedLine = line.Trim();
                    
                    // 跳过注释和空行
                    if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("#"))
                        continue;

                    // 检查是否进入参数定义部分
                    if (trimmedLine.StartsWith("*PARAM"))
                    {
                        inParamSection = true;
                        continue;
                    }

                    // 解析参数行
                    if (inParamSection && trimmedLine.StartsWith("PARAM"))
                    {
                        var parts = trimmedLine.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
                        if (parts.Length >= 6)
                        {
                            try
                            {
                                var paramInfo = new SharedParameterInfo
                                {
                                    Guid = parts[1],
                                    Name = parts[2],
                                    DataType = parts[3],
                                    DataCategory = parts[4],
                                    GroupId = parts[5],
                                    Visible = parts.Length > 6 ? parts[6] : "1",
                                    IsSelected = true
                                };
                                parameters.Add(paramInfo);
                                System.Diagnostics.Debug.WriteLine($"加载参数: {paramInfo.Name} (GUID: {paramInfo.Guid})");
                            }
                            catch (Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine($"第{lineNumber}行解析失败: {ex.Message}");
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine($"第{lineNumber}行格式不正确: {trimmedLine}");
                        }
                    }
                }

                Parameters = new ObservableCollection<SharedParameterInfo>(parameters);
                System.Diagnostics.Debug.WriteLine($"共加载了 {parameters.Count} 个共享参数");
            }
            catch (Exception ex)
            {
                StatusMessage = $"加载共享参数配置失败：{ex.Message}";
                Parameters = new ObservableCollection<SharedParameterInfo>();
                System.Diagnostics.Debug.WriteLine($"加载共享参数失败: {ex}" );
            }
        }

        [RelayCommand]
        private void SelectAllFamilyTypes()
        {
            foreach (var familyType in FamilyTypes)
            {
                familyType.IsSelected = true;
            }
        }

        [RelayCommand]
        private void UnselectAllFamilyTypes()
        {
            foreach (var familyType in FamilyTypes)
            {
                familyType.IsSelected = false;
            }
        }

        [RelayCommand]
        private void SelectAllParameters()
        {
            foreach (var parameter in Parameters)
            {
                parameter.IsSelected = true;
            }
        }

        [RelayCommand]
        private void UnselectAllParameters()
        {
            foreach (var parameter in Parameters)
            {
                parameter.IsSelected = false;
            }
        }

        [RelayCommand]
        private void BrowseSharedParameterFile()
        {
            var dialog = new Microsoft.Win32.OpenFileDialog
            {
                Filter = "共享参数文件 (*.txt)|*.txt|所有文件 (*.*)|*.*",
                Title = "选择共享参数文件",
                DefaultExt = ".txt",
                CheckFileExists = true,
                InitialDirectory = Path.GetDirectoryName(SharedParameterFilePath)
            };

            if (!string.IsNullOrEmpty(SharedParameterFilePath) && File.Exists(SharedParameterFilePath))
            {
                dialog.FileName = Path.GetFileName(SharedParameterFilePath);
            }

            if (dialog.ShowDialog() == true)
            {
                SharedParameterFilePath = dialog.FileName;
                // 重新加载参数
                LoadSharedParameters();
            }
        }

        [RelayCommand]
        private async void StartProcess()
        {
            try
            {
                IsProcessing = true;
                ProgressValue = 0;
                StatusMessage = "开始处理...";

                var selectedFamilyTypes = FamilyTypes.Where(f => f.IsSelected).ToList();
                var selectedParameters = Parameters.Where(p => p.IsSelected).ToList();

                if (selectedFamilyTypes.Count == 0)
                {
                    StatusMessage = "请选择要处理的族类型";
                    return;
                }

                if (selectedParameters.Count == 0)
                {
                    StatusMessage = "请选择要添加的参数";
                    return;
                }

                // 设置处理器数据
                _handler.SetData(selectedFamilyTypes, selectedParameters, this);

                // 触发外部事件
                _externalEvent.Raise();
            }
            catch (Exception ex)
            {
                StatusMessage = $"启动处理失败：{ex.Message}";
                IsProcessing = false;
            }
        }

        public void UpdateProgress(int current, int total, string currentItem)
        {
            // 使用窗口的 Dispatcher 而不是 Application.Current
            _window.Dispatcher.Invoke(() =>
            {
                ProgressValue = total > 0 ? (double)current / total * 100 : 0;
                ProgressText = $"{current}/{total}";
                StatusMessage = $"正在处理：{currentItem}";
            });
        }

        public void ProcessCompleted(string message)
        {
            _window.Dispatcher.Invoke(() =>
            {
                IsProcessing = false;
                StatusMessage = message;
                ProgressValue = 100;
            });
        }

        public void ProcessError(string error)
        {
            _window.Dispatcher.Invoke(() =>
            {
                IsProcessing = false;
                StatusMessage = $"处理失败：{error}";
            });
        }
    }

    /// <summary>
    /// 族类型信息
    /// </summary>
    public partial class FamilyTypeInfo : ObservableObject
    {
        [ObservableProperty]
        private ElementId _familyTypeId;

        [ObservableProperty]
        private string _familyTypeName;

        [ObservableProperty]
        private string _familyName;

        [ObservableProperty]
        private int _instanceCount;

        [ObservableProperty]
        private bool _isSelected;
    }

    /// <summary>
    /// 共享参数信息
    /// </summary>
    public partial class SharedParameterInfo : ObservableObject
    {
        [ObservableProperty]
        private string _guid;

        [ObservableProperty]
        private string _name;

        [ObservableProperty]
        private string _dataType;

        [ObservableProperty]
        private string _dataCategory;

        [ObservableProperty]
        private string _groupId;

        [ObservableProperty]
        private string _visible;

        [ObservableProperty]
        private bool _isSelected;
    }
}

namespace CodRevit.ViewModels
{
    /// <summary>
    /// 添加参数外部事件处理器
    /// </summary>
    public class AddParameterHandler : IExternalEventHandler
{
    private List<FamilyTypeInfo> _familyTypes;
    private List<SharedParameterInfo> _parameters;
    private AddParameterViewModel _viewModel;

    public void SetData(List<FamilyTypeInfo> familyTypes, List<SharedParameterInfo> parameters, AddParameterViewModel viewModel)
    {
        _familyTypes = familyTypes;
        _parameters = parameters;
        _viewModel = viewModel;
    }

    public void Execute(UIApplication app)
    {
        try
        {
            Document doc = app.ActiveUIDocument.Document;
            int processedCount = 0;
            int totalCount = _familyTypes.Count;
            var processedFamilies = new List<string>();

            foreach (var familyTypeInfo in _familyTypes)
            {
                processedCount++;
                _viewModel.UpdateProgress(processedCount, totalCount, familyTypeInfo.FamilyName);

                try
                {
                    // 直接获取族（因为FamilyTypeId现在存储的是族ID）
                    var family = doc.GetElement(familyTypeInfo.FamilyTypeId) as Family;
                    if (family == null) continue;
                    
                    try
                    {
                        Document familyDoc = doc.EditFamily(family);
                        if (familyDoc == null)
                        {
                            processedFamilies.Add($"❌ {familyTypeInfo.FamilyName}: 无法打开族文档");
                            continue;
                        }

                        // 检查文档是否只读
                        if (familyDoc.IsReadOnly)
                        {
                            processedFamilies.Add($"⚠️ {familyTypeInfo.FamilyName}: 族文档为只读，跳过处理");
                            continue; // 不需要关闭，由Revit管理
                        }

                        // 在族文档中添加参数
                        bool hasChanges = false;
                        var addedParams = new List<string>();

                        using (Transaction trans = new Transaction(familyDoc, "添加共享参数"))
                        {
                            TransactionStatus transStatus = trans.Start();
                            if (transStatus != TransactionStatus.Started)
                            {
                                processedFamilies.Add($"❌ {familyTypeInfo.FamilyName}: 无法启动事务");
                                continue;
                            }

                            try
                            {
                                // 使用配置的共享参数文件路径
                                string configPath = _viewModel.SharedParameterFilePath;

                                // 检查文件是否存在
                                if (string.IsNullOrEmpty(configPath) || !File.Exists(configPath))
                                {
                                    if (trans.GetStatus() == TransactionStatus.Started)
                                    {
                                        trans.RollBack();
                                    }
                                    throw new Exception($"未找到共享参数文件: {configPath}");
                                }

                                app.Application.SharedParametersFilename = configPath;
                                DefinitionFile defFile = app.Application.OpenSharedParameterFile();

                                if (defFile == null)
                                {
                                    if (trans.GetStatus() == TransactionStatus.Started)
                                    {
                                        trans.RollBack();
                                    }
                                    throw new Exception("无法打开共享参数文件");
                                }

                                FamilyManager famMan = familyDoc.FamilyManager;

                                foreach (var paramInfo in _parameters)
                                {
                                    try
                                    {
                                        // 检查参数是否已存在
                                        var existingParam = famMan.Parameters.Cast<FamilyParameter>()
                                            .FirstOrDefault(p => p.Definition.Name == paramInfo.Name);

                                        if (existingParam == null)
                                        {
                                            // 查找参数定义
                                            ExternalDefinition definition = FindParameterDefinition(defFile, paramInfo.Guid);
                                            if (definition != null)
                                            {
                                                // 使用全局设置的参数分组和实例设置
                                                famMan.AddParameter(definition, _viewModel.GlobalParameterGroup, _viewModel.GlobalIsInstance);
                                                addedParams.Add($"{paramInfo.Name}({(_viewModel.GlobalIsInstance ? "实例" : "类型")})");
                                                hasChanges = true;
                                            }
                                            else
                                            {
                                                System.Diagnostics.Debug.WriteLine($"未找到参数定义: {paramInfo.Name} (GUID: {paramInfo.Guid})");
                                            }
                                        }
                                    }
                                    catch (Exception paramEx)
                                    {
                                        // 单个参数添加失败不影响其他参数，记录但继续
                                        System.Diagnostics.Debug.WriteLine($"参数 {paramInfo.Name} 添加失败: {paramEx.Message}");
                                        continue;
                                    }
                                }

                                if (hasChanges)
                                {
                                    // 检查事务状态后提交
                                    if (trans.GetStatus() == TransactionStatus.Started)
                                    {
                                        TransactionStatus commitStatus = trans.Commit();
                                        if (commitStatus == TransactionStatus.Committed)
                                        {
                                            // 加载回项目，使用IFamilyLoadOptions
                                            familyDoc.LoadFamily(doc, new FamilyLoadOptions());
                                            processedFamilies.Add($"✅ {familyTypeInfo.FamilyName}: 添加了 {addedParams.Count} 个参数 ({string.Join(", ", addedParams)})");
                                        }
                                        else
                                        {
                                            processedFamilies.Add($"❌ {familyTypeInfo.FamilyName}: 事务提交失败");
                                        }
                                    }
                                    else
                                    {
                                        processedFamilies.Add($"❌ {familyTypeInfo.FamilyName}: 事务状态异常");
                                    }
                                }
                                else
                                {
                                    if (trans.GetStatus() == TransactionStatus.Started)
                                    {
                                        trans.RollBack();
                                    }
                                    processedFamilies.Add($"ℹ️ {familyTypeInfo.FamilyName}: 所有参数已存在");
                                }
                            }
                            catch (Exception ex)
                            {
                                if (trans.GetStatus() == TransactionStatus.Started)
                                {
                                    trans.RollBack();
                                }
                                processedFamilies.Add($"❌ {familyTypeInfo.FamilyName}: {ex.Message}");
                            }
                        }
                        // 注意：不需要手动关闭familyDoc，Revit会自动管理
                    }
                    catch (Exception ex)
                    {
                        processedFamilies.Add($"❌ {familyTypeInfo.FamilyName}: {ex.Message}");
                    }
                }
                catch (Exception ex)
                {
                    processedFamilies.Add($"❌ {familyTypeInfo.FamilyName}: {ex.Message}");
                }
            }

            // 显示处理结果
            string resultMessage = $"处理完成！\n\n" + string.Join("\n", processedFamilies);
            _viewModel.ProcessCompleted(resultMessage);

            TaskDialog.Show("处理结果", resultMessage);
        }
        catch (Exception ex)
        {
            _viewModel.ProcessError(ex.Message);
        }
    }

    private ExternalDefinition FindParameterDefinition(DefinitionFile defFile, string guid)
    {
        // 清理和标准化GUID格式
        string cleanGuid = guid.Replace("{",$"").Replace("}",$"").Replace("-",$"");
        
        foreach (DefinitionGroup group in defFile.Groups)
        {
            foreach (ExternalDefinition def in group.Definitions)
            {
                string defGuid = def.GUID.ToString().Replace("{",$"").Replace("}",$"").Replace("-",$"");
                if (string.Equals(defGuid, cleanGuid, StringComparison.OrdinalIgnoreCase))
                {
                    return def;
                }
            }
        }
        return null;
    }

    public string GetName()
    {
        return "AddParameterHandler";
    }
}

/// <summary>
/// 参数分组信息
/// </summary>
public partial class ParameterGroupInfo : ObservableObject
{
    [ObservableProperty]
    private BuiltInParameterGroup _group;

    [ObservableProperty]
    private string _displayName;

    public ParameterGroupInfo(BuiltInParameterGroup group, string displayName)
    {
        Group = group;
        DisplayName = displayName;
    }
}

/// <summary>
/// 族加载选项处理器
/// </summary>
public class FamilyLoadOptions : IFamilyLoadOptions
{
    public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
    {
        overwriteParameterValues = true;
        return true;
    }

    public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
    {
        source = FamilySource.Family;
        overwriteParameterValues = true;
        return true;
    }
}
}